package com.doudanhua.basecode.redis;

import com.sun.org.apache.bcel.internal.generic.RET;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.function.Supplier;

/**
 * @Author zhangqian
 * @Description TODO
 * @Date 2022/11/9 11:56
 */
@Component
public class RedisLock {
    private final RedisLockRegistry redisLockRegistry;

    public RedisLock(RedisLockRegistry redisLockRegistry) {
        this.redisLockRegistry = redisLockRegistry;
    }

    public Lock lock(String key) {
        final Lock lock = redisLockRegistry.obtain(key);
        return lock;
    }

    public void unLock(String key) {
        final Lock lock = redisLockRegistry.obtain(key);
        lock.unlock();
    }

    public void tryLock(String key, long time, TimeUnit timeUnit) throws InterruptedException {
        final Lock lock = redisLockRegistry.obtain(key);
        lock.tryLock(time, timeUnit);
    }

    public <T> T lock(String key, long time, TimeUnit timeUnit, Supplier<T> supplier) throws Exception {
        final Lock lock = lock(key);
        boolean getLock = true;
        try {
            if (lock.tryLock(time, timeUnit)) {
                final T t = supplier.get();
                return t;
            } else {
                getLock = false;
                throw new Exception("获取锁失败");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
            Thread.currentThread().interrupt();
            throw new Exception("获取锁失败");
        } finally {
            if (getLock) {
                lock.unlock();
            }
        }
    }
}
